#include "util/graph_io.hpp"
#include "util/vecs_io.hpp"
#include "util/time_memory.hpp"
#include "util/ground_truth.hpp"

#define TEST

#include "gradient.hpp"

using namespace std;
using namespace GraphGradient;

void save_res(char *base_path, vector<double> data) {
    //mkdir
    if (mkdir(base_path, 0755) == -1) {
        printf("directory exists, save directly\n");
    }
    mkdir(base_path, 0755);

    char res_path[256];
    std::sprintf(res_path, "%s/edge_proportion.txt", base_path);
    std::ofstream outfile;
    outfile.open(res_path);
    int data_size = data.size();
    for (int i = 0; i < data_size; i++) {
        outfile << data[i] << " ";
    }
    outfile << std::endl;
    outfile.close();

}

int main() {
    const char *dataset_name = "sift";
    const int M = 40;
    const char *graph_method = "SSG";
    const int ef_construction = 100;
    const int random_seed = 100;

    int n_query, top_k, n_base, data_dim;
    top_k = 10;

    vector<float *> data = read_data(dataset_name, n_query, top_k, n_base, data_dim);
    float *base = data[0];
    float *query = data[1];
    int *gnd = (int *) data[2];

    printf("dataset %s, M %d, efConstruction %d\n", dataset_name, M, ef_construction);

    //build index
    GraphGradient::GraphGradient graphGradient(data_dim, n_base, random_seed + 1);
    {
        char path[256];
        sprintf(path, "../data/%s/%s.graph", dataset_name, graph_method);
        vector <vector<int>> graph;
        int enter_point;
        read_graph<int>(path, graph, enter_point);

        vector <vector<double>> graph_distance;
        sprintf(path, "../data/%s/%s-distance.graph", dataset_name, graph_method);
        read_graph<double>(path, graph_distance, enter_point);

        graphGradient.add(base, graph, graph_distance, enter_point);
        for (int i = 0; i < n_base; i++) {
            graph[i].clear();
            graph_distance[i].clear();
        }
        graph.clear();
        graph_distance.clear();
    }
    double avg_n_gradient, avg_n_neighbors;
    vector<double> gradient_proportion = graphGradient.get_gradient_proportion_l(avg_n_gradient, avg_n_neighbors);

    printf("avg_n_gradient %5.2lf, avg_n_neighbors %5.2lf\n", avg_n_gradient, avg_n_neighbors);

    char base_path[256];
    std::sprintf(base_path, "../result/%s_%d_%s_%s_%d_%d", dataset_name, top_k, "gradient", graph_method, M,
                 ef_construction);

    save_res(base_path, gradient_proportion);
    return 0;
}

